package com.xbongbong.sys.model.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.sys.domain.dao.DepartmentDao;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DepartmentTreeTypeEnum;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserDepartmentModel;
import com.xbongbong.sys.model.UserModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author kaka
 * @time 2018-9-4 16:51
 */
@Service("departmentModel")
@Slf4j
public class DepartmentModelImpl implements DepartmentModel {

    /**
     * 列表只需取出核心字段
     */
    private static final String LIST_COLUMNS = "corpid,id,name,parent_id,dep_id_router,level,sort,add_time,update_time,del";

    /**
     * 此处有破坏规约之处，后期再整理
     */
    @Resource
    private UserModel userModel;
    @Resource
    private UserDepartmentModel userDepartmentModel;

    @Resource
    private DepartmentDao departmentDao;
    @Resource
    private PaasRedisHelper paasRedisHelper;


    @Override
    public Integer insert(DepartmentEntity entity) {
        // 部门是通过钉钉同步的，id由钉钉生成，这边不能设置成null
        return departmentDao.insert(entity);
    }

    @Override
    public Integer update(DepartmentEntity entity){
        return departmentDao.update(entity);
    }

    @Override
    public void updateBatch(List<DepartmentEntity> departmentList, String corpid){
        departmentDao.updateBatch(departmentList, corpid);
    }

    @Override
    public void batchUpdateDel(Integer del, Integer updateTime, List<Long> idIn, String corpid){
        departmentDao.batchUpdateDel(del,updateTime,idIn,corpid);
    }

    @Override
    public void batchUpdateDelNotIn(Integer del, Integer updateTime, List<Long> idNotIn, String corpid){
        departmentDao.batchUpdateDelNotIn(del,updateTime,idNotIn,corpid);
    }

    @Override
    public Integer deleteByKey(String key, String corpid) {
        return departmentDao.deleteByKey(key, corpid);
    }

    @Override
    public DepartmentEntity getByKey( Long departmentId, String corpid){
        return departmentDao.getByKey(departmentId, corpid);
    }

    @Override
    public List<DepartmentEntity> findAllDepartment(String corpid, boolean showHidden) throws XbbException {
        Map<String, Object> param = new HashMap<>(8);
        param.put("corpid", corpid);
        if (StringUtil.isEmpty(corpid)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "缺少corpid");
        }
        if (showHidden) {
            param.put("negDel", 1);
        } else {
            param.put("del", 0);
        }
        //钉钉的顺序按sort正序
        param.put("orderByStr", "sort");
        return findEntitys(param);
    }

    @Override
    public List<DepartmentEntity> findAllDepartment(String corpid, boolean showHidden, Map<String, List<Long>> deptConditions) {
        Map<String, Object> param = new HashMap<>(8);
        //增加部门Id查询条件
        if (Objects.nonNull(deptConditions) && deptConditions.size() != 0){
            param.put("deptOptionalRange", deptConditions);
        }
        param.put("corpid", corpid);
        if (showHidden) {
            param.put("negDel", 1);
        } else {
            param.put("del", 0);
        }
        //钉钉的顺序按sort正序
        param.put("orderByStr", "sort");
        return findEntitys(param);
    }

    @Override
    public List<DepartmentEntity> findEntitys(Map<String, Object> param) {
        if(Objects.equals(param.get(ParameterConstant.COLUMNS),null)){
            param.put(ParameterConstant.COLUMNS, LIST_COLUMNS);
        }
        return departmentDao.findEntitys(param);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return departmentDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public JSONArray getDepartmentJsonTree(String corpid, List<UserEntity> userList, String type, boolean showHidden, boolean simple) throws XbbException {
        List<DepartmentEntity> allDep = findAllDepartment(corpid, showHidden);
        // 部门map,键为部门id,值为部门实体
        Map<Long, DepartmentEntity> depMap = BeanUtil.convertListToMap(allDep, "id");
        // 将游离的部分转换成顶级部门
        allDep = freeDepToTopDep(allDep, depMap);
        //所有顶级部门
        JSONArray departmentJsonArray = new JSONArray();

        //抽出所有顶级部门
        for(DepartmentEntity departmentEntity : allDep){
            //建公司部门树
            if(departmentEntity.getParentId().equals(0L)){
                JSONObject json = formatDepJSONObject(allDep, departmentEntity, simple);
                departmentJsonArray.add(json);
                break;
            }
        }

        // TODO staff 相关逻辑 参见 saas 项目中同名方法，目前还不需要

        return departmentJsonArray;
    }


    @Override
    public JSONArray getDepartmentJsonTree(String corpid, List<UserEntity> userList, String type, boolean showHidden, boolean simple, Map<String, List<Long>> deptConditions) throws XbbException {
        List<DepartmentEntity> filterDep = findAllDepartment(corpid, showHidden, deptConditions);
        //将所有部门置为顶级部门
        for (DepartmentEntity item : filterDep) {
            item.setParentId(0L);
        }
        //所有顶级部门
        JSONArray departmentJsonArray = new JSONArray();

        //抽出所有顶级部门
        for(DepartmentEntity departmentEntity : filterDep){
            //建公司部门树
            if(departmentEntity.getParentId().equals(0L)){
                JSONObject json = formatDepJSONObject(filterDep, departmentEntity, simple);
                departmentJsonArray.add(json);
            }
        }

        return departmentJsonArray;
    }

    @Override
    public JSONArray getDepartmentJsonTree(String corpid, boolean showHidden) throws XbbException {
        return getDepartmentJsonTree(corpid, null, DepartmentTreeTypeEnum.DEPARTMENT.getType(), showHidden, false);
    }

    @Override
    public JSONArray getSubDeptJsonTree(String corpid, boolean showHidden, List<DepartmentEntity> departmentEntities, Boolean simple) throws XbbException {
        List<DepartmentEntity> allDep = findAllDepartment(corpid, showHidden);
        return getSimpleJsonTree(allDep, departmentEntities, simple);
    }

    @Override
    public JSONArray getSubDeptJsonTreeByDeptId(String corpid, boolean showHidden, List<DepartmentEntity> departmentEntities, Boolean simple, List<DepartmentEntity> selectDepartmentList) throws XbbException {

        return getSimpleJsonTree(selectDepartmentList, departmentEntities, simple);
    }

    /**
     * 构建部门树
     * @param allDep 构建树的部门列表
     * @param departmentEntities 权限内的部门
     * @param simple 简单结构的部门树
     * @return 部门树
     * @throws XbbException
     */
    private JSONArray getSimpleJsonTree(List<DepartmentEntity> allDep, List<DepartmentEntity> departmentEntities, boolean simple) throws XbbException {
        // 部门map,键为部门id,值为部门实体
        Map<Long, DepartmentEntity> depMap = BeanUtil.convertListToMap(allDep, "id");
        // 将游离的部分转换成顶级部门
        allDep = freeDepToTopDep(allDep, depMap);
        //所有顶级部门
        JSONArray departmentJsonArray = new JSONArray();

        //抽出所有顶级部门
        for(DepartmentEntity departmentEntity : departmentEntities){
            //建公司部门树
            JSONObject json = formatDepJSONObject(allDep, departmentEntity, simple);
            departmentJsonArray.add(json);
        }
        // TODO staff 相关逻辑 参见 saas 项目中同名方法，目前还不需要

        return departmentJsonArray;
    }

    @Override
    public JSONArray getDepartmentSimpleJsonTree(String corpid, boolean showHidden) throws XbbException {
        return getDepartmentJsonTree(corpid, null, DepartmentTreeTypeEnum.DEPARTMENT.getType(), showHidden, true);
    }

    @Override
    public JSONArray getDepartmentSimpleJsonTree(String corpid, boolean showHidden, Map<String, List<Long>> deptConditions) throws XbbException {
        return getDepartmentJsonTree(corpid, null, DepartmentTreeTypeEnum.DEPARTMENT.getType(), showHidden, true, deptConditions);
    }

    @Override
    public List<DepartmentEntity> getByDepIdIn(String corpid, Collection<Long> depIdIn) {
        Map<String, Object> param = new HashMap<>(8);
        param.put("corpid", corpid);
        param.put("idIn", depIdIn);
        param.put("del", 0);
        return findEntitys(param);
    }

    @Override
    public List<Long> getDepIds(Map<String, Object> param) {
        return departmentDao.getDepIds(param);
    }

    @Override
    public List<DepartmentEntity> findEntitysByDepartmentIds(List<Long> departmentIds, String corpid) {
        return departmentDao.findEntitysByDepartmentIds(departmentIds, corpid);
    }

    @Override
    public List<Long> getSubDepIdList(String corpid, Collection<Long> depIdIn) {
        return getSubDepIdList(corpid, depIdIn, false);
    }

    /**
     * 获取部门的下面的所有子部门的部门id列表
     * @param corpid 公司corpid
     * @param depIdIn 要获取子部门ids的所有部门ids
     * @param showHidden 是否考虑隐藏部门（即del = 2的部门），true 显示，false 不显示
     * @return depIdIn 及其递归子部门的部门id列表
     */
    @Override
    public List<Long> getSubDepIdList(String corpid, Collection<Long> depIdIn, boolean showHidden){
        List<Long> list = new ArrayList<>();
        if (depIdIn == null || depIdIn.size() == 0) {
            return list;
        }
        // 设置参数 主要增加corpid参数和routerRegexp参数，以及将 negDel 置为1
        Map<String, Object> param = formatSubDepListParam(corpid, depIdIn, showHidden);

        Integer start = 0;
        //步长
        Integer pageNum = 10000;
        /************查询指标************/
        for(;start <= Integer.MAX_VALUE; start = start + pageNum){
            param.put("start", start);
            param.put("pageNum", pageNum);
            List<Long> perList = getDepIds(param);
            list.addAll(perList);
            //查询出的结果少于步长，肯定是没有数据了
            if (perList.size() < pageNum) {
                break;
            }
        }
        return list;
    }

    @Override
    public List<DepartmentEntity> getSubOneLevel(String corpid, Long depId) {
        return getSubOneLevel(corpid, depId, false);
    }
    @Override
    public List<DepartmentEntity> getSubOneLevel(String corpid, Long depId, boolean containSup) {
        List<DepartmentEntity> list = new ArrayList<>();
        if (depId == null) {
            return list;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        if (containSup) {
            param.put("parentAndSub", depId);
        } else {
            param.put("parentId", depId);
        }
        param.put("del", 0);
        Integer start = 0;
        //步长
        Integer pageNum = 5000;
        /************查询指标************/
        for(;start <= Integer.MAX_VALUE; start = start + pageNum){
            param.put("start", start);
            param.put("pageNum", pageNum);
            List<DepartmentEntity> perList = findEntitys(param);
            list.addAll(perList);
            if (perList.size() < pageNum) {
                break;
            }
        }
        return list;
    }
    @Override
    public List<DepartmentEntity> getSubOneLevelFromJedis(String corpid, Long depId, boolean containSup) {
        String key = corpid + "_" + depId + "_" + containSup;
        String redisDepId = paasRedisHelper.getValue(RedisPrefixConstant.SUB_ONE_LEVEL, key);
        List<DepartmentEntity> list = JsonHelperUtil.parseArray(redisDepId, DepartmentEntity.class);
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        }
        // 下一级子部门列表
        list = getSubOneLevel(corpid, depId, containSup);
        paasRedisHelper.setValue(RedisPrefixConstant.SUB_ONE_LEVEL, key, list, RedisTimeConstant.HOUR_DURATION);
        return list;
    }

    /**
     * 获取部门的下面的所有子部门
     *
     * @param corpid 公司id
     * @param depIdIn 要获取子部门ids的所有部门ids
     * @param showHidden 是否考虑隐藏部门（即del = 2的部门），true 显示，false 不显示
     * @return 返回depIdIn的所有的子部门（包含本身）
     * @since performance-v1.0
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * @author kaka
     * 创建时间：2018年11月2日 下午4:08:55
     * 修改时间：2018-11-5 by zcp 参数depIdIn由list类型改为set类型（因缓存方案要用到hashCode，list的hashCode对内部的顺序有严格限制）
     */
    @Override
    public List<DepartmentEntity> getSubDepList(String corpid, Collection<Long> depIdIn, boolean showHidden){
        List<DepartmentEntity> list = new ArrayList<>();
        if (depIdIn == null || depIdIn.size() == 0) {
            return list;
        }
        // 设置参数 主要增加corpid参数和routerRegexp参数，以及将 negDel 置为1
        Map<String, Object> param = formatSubDepListParam(corpid, depIdIn, showHidden);

        Integer start = 0;
        //步长
        Integer pageNum = 10000;
        /************查询指标************/
        for(;start <= Integer.MAX_VALUE; start = start + pageNum){
            param.put("start", start);
            param.put("pageNum", pageNum);
            List<DepartmentEntity> perList = findEntitys(param);
            list.addAll(perList);
            //查询出的结果少于步长，肯定是没有数据了
            if (perList.size() < pageNum) {
                break;
            }
        }
        return list;
    }
    /**
     * 从缓存获取部门的子部门
     * 参数depIdIn由list类型改为set类型（因缓存方案要用到hashCode，list的hashCode对内部的顺序有严格限制）
     *
     * @param corpid  公司id
     * @param depIdIn 部门ids
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-01-31 16:30
     * @version v1.0
     * @since v1.0
     * @update by zcp 从main-service移入 2019-03-27
     */
    @Override
    public List<DepartmentEntity> getSubDepListFromJedis(String corpid, Set<Long> depIdIn) {
        if(depIdIn == null) {
            depIdIn = new HashSet<>();
        }

        String key = corpid + "_" + depIdIn.hashCode();
        String redisDepIdIn = paasRedisHelper.getValue(RedisPrefixConstant.SUB_DEP_LIST, key);
        List<DepartmentEntity> list = JsonHelperUtil.parseArray(redisDepIdIn, DepartmentEntity.class);
        if (list != null && list.size() > 0) {
            return list;
        }
        List<Long> depIds = new ArrayList<>();
        if (depIdIn.size() == 0) {
            depIds.add(-1L);
        } else {
            depIds.addAll(depIdIn);
        }

        // 子部门列表
        list = getSubDepList(corpid, depIds, false);

        paasRedisHelper.setValue(RedisPrefixConstant.SUB_DEP_LIST, key, list, RedisTimeConstant.TEN_MINUTES);
        return list;
    }

    @Override
    public void clearEmptyDepartment(String corpid){
        resetEmptyDepartment(corpid);

        Map<String,Object> param = new HashMap<>(16);
        param.put("corpid", corpid);
        param.put("del", 0);

        Set<Long> allDepIds = new HashSet<>(getDepIds(param));

        param.clear();
        param.put("corpid", corpid);
        param.put("del", 0);
        List<String> userIds = userModel.getUserIds(param);
        if(userIds.size() == 0){
            //没员工，特殊情况，不处理
            return;
        }
        param.clear();
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("userIdIn", userIds);
        List<Long> usingDepIds = userDepartmentModel.getDepIds(param);

        if(usingDepIds.size()>0){
            //父部门
            param.clear();
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("idIn", usingDepIds);
            List<String> depIdRouters = getDepIdRouters(param);
            for(String depIdRouter : depIdRouters){
                List<String> routerStr = StringUtil.roleIdToList(depIdRouter);
                if (routerStr == null) {
                    continue;
                }
                List<Long> routerIds = new ArrayList<>();
                for(String str : routerStr){
                    routerIds.add(Long.valueOf(str));
                }
                usingDepIds.addAll(routerIds);
            }
        }

        allDepIds.removeAll(usingDepIds);
        Set<Long> emptyDepIds = new HashSet<>(allDepIds);

        if(!emptyDepIds.isEmpty()){
            emptyDepIds.remove(1L);
            if(!emptyDepIds.isEmpty()){
                batchUpdateDel(2, DateUtil.getInt(),new ArrayList<>(emptyDepIds),corpid);
            }
        }
    }

    @Override
    public void batchUpdateDelByDel(Integer del, Integer updateTime, Integer conditionDel, String corpid) {
        departmentDao.batchUpdateDelByDel(del,updateTime,conditionDel,corpid);
    }

    @Override
    public Map<Long, DepartmentEntity> getDeptsMap(String corpid, List<Long> depIdIn){
        //存储结果的map
        Map<Long, DepartmentEntity> deptsMap = new HashMap<>();
        if (depIdIn != null && depIdIn.size() == 0) {
            return deptsMap;
        }

        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        if (depIdIn != null) {
            param.put("idIn", depIdIn);
        }
        //此处不用del=0
        List<DepartmentEntity> depts = findEntitys(param);

        for (DepartmentEntity dept : depts) {
            deptsMap.put(dept.getId(), dept);
        }
        return deptsMap;
    }

    @Override
    public List<Long> getDepartmentIdsByRegexp(String corpid, String routerRegexp) {
        return departmentDao.getDepartmentIdsByRegexp(corpid, routerRegexp);
    }

    @Override
    public Integer deleteByKeys(List<Long> keys, String corpid) {
        return departmentDao.deleteByKeys(keys, corpid);
    }

    @Override
    public DepartmentEntity getByKeyIgnoreDel(String key, String corpid) {
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("id", key);

        /*
         * 此处getByKey方法返回的是del=0的记录，这里del=1的记录也可以，最后会将其del置为0
         */
        List<DepartmentEntity> depList = departmentDao.findEntitys(param);

        return depList.size() > 0 ? depList.get(0) : null;
    }

    @Override
    public Map<String, String> formatUserDepNames(String corpid, List<UserEntity> userList) {
        // 员工userId--所属部门id列表
        Map<String, List<Long>> userDepIdsMap = new HashMap<>(userList.size());
        // 查询部门名称用
        Set<Long> depIdIn = new HashSet<>();
        for (UserEntity entity : userList) {
            String belongdeptStr = entity.getDepartment();
            if (!StringUtil.isEmpty(belongdeptStr)) {
                // 员工所属部门
                List<Long> belongdeptList = JSONArray.parseArray(belongdeptStr, Long.class);
                depIdIn.addAll(belongdeptList);
                userDepIdsMap.put(entity.getUserId(), belongdeptList);
            }
        }
        /*
         处理员工所属部门名
         */
        // userId--员工所在部门名称合集
        Map<String, String> nameUserDepsMap = new HashMap<>(userList.size());
        // 部门id--部门名称
        List<DepartmentEntity> departmentList = getByDepIdIn(corpid, depIdIn);
        Map<Long, String> nameDepMap = new HashMap<>(departmentList.size());
        for (DepartmentEntity departmentEntity : departmentList) {
            nameDepMap.put(departmentEntity.getId(), departmentEntity.getName());
        }
        for (UserEntity entity : userList) {
            String uid = entity.getUserId();
            List<Long> depIdList = userDepIdsMap.get(uid);
            StringBuilder depNames = new StringBuilder();
            if (depIdList != null) {
                for (Long did : depIdList) {
                    String name = nameDepMap.get(did);
                    if (StringUtil.isEmpty(name)) {
                        continue;
                    }
                    if (depNames.length() != 0) {
                        depNames.append(",");
                    }
                    depNames.append(name);
                }
            }
            nameUserDepsMap.put(uid, depNames.toString());
        }
        return nameUserDepsMap;
    }

    @Override
    public List<DepartmentEntity> getDepartmentNamesByIds(String corpId, Collection<Long> depIdIn, boolean ignoreDel) {
        if (CollectionUtils.isEmpty(depIdIn)) {
            return new ArrayList<>();
        }
        Map<String, Object> param = new HashMap<>(8);
        param.put(ParameterConstant.COLUMNS, "id, name");
        param.put("corpid", corpId);
        param.put("idIn", depIdIn);
        if (!ignoreDel) {
            param.put("del", 0);
        }
        return findEntitys(param);
    }

    /**
     * 通过名称获取部门
     *
     * @param names  部门名称，"-"分割
     * @param corpid 公司id
     * @return Map
     * @author GuoJun.HU
     * @date 2019/5/21 16:21
     * @since V1.0
     */
    @Override
    public Map<String, Object> getDepIdByNames(String names, String corpid) {
        if(StringUtil.isEmpty(names)){
            return null;
        }

        Map<String, Object> retMap = new HashMap<>();

        String[] nameArray = names.split("-");
        DepartmentEntity retEntity = null;//返回的entity
        Map<String,Object> param = new HashMap<>();
        DepartmentEntity supDepEntity = null;//当前处理的父entity
        //TODO 这部分逻辑暂时不用，用到一定要改写
        DepartmentEntity entity = null;//当前处理的entity
        List<String> noDepNameList = new ArrayList<String>();//不存在的部门名称
        Integer code = 1;
        for(int i = 0 ; i<nameArray.length ; i++){ //遍历部门数组
            if(supDepEntity != null){
                param.put("parentId", supDepEntity.getId());
            }
            param.put("name", nameArray[i]);
            param.put("corpid", corpid);
            param.put("del", 0);
            List<DepartmentEntity> departmentEntityList = this.findEntitys(param);
            Integer num = departmentEntityList.size();

            if(num == 0){
                //部门不存在，创建------现在不能创建，返回提示即可
                code = 3;
                //说明有部门不存在的情况
                noDepNameList.add(nameArray[i]);
                //部门不存在，则结束
                break;
            }else{
                entity = departmentEntityList.get(0);
            }
            supDepEntity = entity;

            if(i == nameArray.length-1){
                //最后一个
                retEntity = entity;
            }
        }

        retMap.put("code", code);
        retMap.put("name", noDepNameList);
        retMap.put("retEntity", retEntity);

        return retMap;
    }

    //==================== private method ====================

    /**
     * 将游离的部分转换成顶级部门
     */
    private List<DepartmentEntity> freeDepToTopDep(List<DepartmentEntity> allDep, Map<Long, DepartmentEntity> depMap) {
        if(allDep != null){
            for(DepartmentEntity dep : allDep){
                Long parentId = dep.getParentId();
                if(!depMap.containsKey(parentId) && !parentId.equals(0L)){
                    dep.setParentId(1L);
                }
            }
        }
        return allDep;
    }

    /**
     * 获取子树
     * @param allDepartmentList 所有部门列表
     * @param parentId 部门父id，需要获取该id下的所有部门结构
     * @param simple 是否返回简单格式，为true简单格式，为false与SAAS结构一致
     * @return parentId 下的部门树
     */
    private JSONArray getSubDepartmentTree(List<DepartmentEntity> allDepartmentList, Long parentId, boolean simple){

        String childrenText = "nodes";
        String depIdText = "pid";
        if (simple) {
            childrenText = "children";
            depIdText = "value";
        }
        JSONArray departmentJsonArray = getSubList(allDepartmentList, parentId, simple);
        if(departmentJsonArray.size() == 0){
            return null;
        }
        for(Object object : departmentJsonArray){
            JSONObject jsonObject = (JSONObject)object;
            if(jsonObject.getString("type").equals(DepartmentTreeTypeEnum.DEPARTMENT.getType())) {
                jsonObject.put(childrenText, getSubDepartmentTree(allDepartmentList, jsonObject.getLong(depIdText), simple));
            }
        }
        return departmentJsonArray;
    }

    /**
     * 获取parentId 下的子部门列表
     * @param allDepartmentList 所有部门
     * @param parentId 父部门id
     * @param simple 是否简单格式，为true则返回简单格式，为false则返回格式与SAAS一致
     * @return parentId下的子部门列表
     */
    private JSONArray getSubList(List<DepartmentEntity> allDepartmentList, Long parentId, boolean simple){
        JSONArray subJsonArray = new JSONArray();
        //抽出子部门
        for(DepartmentEntity departmentEntity : allDepartmentList){
            if(departmentEntity.getParentId().equals(parentId)){
                JSONObject json = formatDepJSONObject(departmentEntity, simple);
                subJsonArray.add(json);
            }
        }
        return subJsonArray;
    }

    /**
     * 用以构建 department 前端显示格式，若simple为true，则为简单格式
     * 否则与SAAS格式一致
     * @param allDep 所有部门数据
     * @param department 部门持久层实体
     * @param simple 是否简单格式
     * @return department 前端显示格式
     */
    private JSONObject formatDepJSONObject(List<DepartmentEntity> allDep, DepartmentEntity department, boolean simple) {
        JSONObject depJson = new JSONObject();
        if (simple) {
            depJson.put("value", department.getId());
            depJson.put("label", department.getName());
            depJson.put("type", "department");
            depJson.put("children", getSubDepartmentTree(allDep,department.getId(), simple));
        } else {
            depJson.put("pid", department.getId());
            depJson.put("text", department.getName());
            depJson.put("routerIds", department.getDepIdRouter());
            depJson.put("type", "department");
            depJson.put("nodes", getSubDepartmentTree(allDep,department.getId(), simple));
        }
        return depJson;
    }

    /**
     * 用以构建 department 前端显示格式，若simple为true，则为简单格式
     * 否则与SAAS格式一致
     * @param department 部门持久层实体
     * @param simple 是否简单格式
     * @return 前端显示格式
     */
    private JSONObject formatDepJSONObject(DepartmentEntity department, boolean simple) {
        JSONObject depJson = new JSONObject();
        if (simple) {
            depJson.put("value", department.getId());
            depJson.put("label", department.getName());
            depJson.put("type", "department");
        } else {
            depJson.put("pid", department.getId());
            depJson.put("text", department.getName());
            depJson.put("routerIds", department.getDepIdRouter());
            depJson.put("type", "department");
        }
        return depJson;
    }

    /**
     * 用于getSubDepList 及 getSubDepIdList 构造参数的方法
     * 主要增加corpid参数和routerRegexp参数
     * @param corpid 公司id
     * @param depIdIn 要获取子部门ids的所有部门ids
     * @param showHidden 是否考虑隐藏部门（即del = 2的部门），true 显示，false 不显示
     * @return 增加
     */
    private Map<String, Object> formatSubDepListParam(String corpid, Collection<Long> depIdIn, boolean showHidden) {
        StringBuilder depIdInRegexp = new StringBuilder();
        int i = 0;
        for (Long depId : depIdIn) {
            depIdInRegexp.append("(\\|").append(depId).append("\\|)");
            if (i != depIdIn.size() - 1) {
                depIdInRegexp.append("|");
            }
            i++;
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (showHidden) {
            param.put("negDel", 1);
        } else {
            param.put("del", 0);
        }

        param.put("corpid", corpid);
        /*
         * 数据库内dep_id_router字段的数值格式为：|1|2|4|
         * 如果想获取部门id为1、2的部门的所有子部门，则等于获取dep_id_router所有包含"|1|"或"|2|"的
         */
        param.put("routerRegexp", depIdInRegexp.toString());
        return  param;
    }

    /**
     * 将全部空部门del设置为0
     * @param corpid 公司id
     */
    private void resetEmptyDepartment(String corpid){
        Integer del = 0;
        Integer updateTime = DateUtil.getInt();
        Integer conditionDel = 2;

        batchUpdateDelByDel(del, updateTime, conditionDel, corpid);
    }

    /**
     * 通过条件获取符合条件的记录的router字段
     * @param param 筛选条件
     * @return 符合条件的几率的router
     */
    private List<String> getDepIdRouters(Map<String, Object> param){
        return departmentDao.getDepIdRouters(param);
    }

    @Override
    public List<Long> getSupDepIdList(String corpid, Collection<Long> depIds, boolean showHidden) {
        List<Long> list = new ArrayList<>();
        if (depIds == null || depIds.size() == 0) {
            return list;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("idIn", depIds);
        if (showHidden) {
            param.put("negDel", 1);
        } else {
            param.put("del", 0);
        }
        List<DepartmentEntity> departmentEntityList = departmentDao.findEntitys(param);
        Set<Long> ids = new HashSet<>();
        for (DepartmentEntity entity : departmentEntityList) {
            String depIdRouter = entity.getDepIdRouter();
            String[] split = depIdRouter.split("\\|");
            for (String id : split) {
                if (!StringUtil.isEmpty(id)) {
                    ids.add(Long.valueOf(id));
                }
            }
        }
        list = new ArrayList<>(ids);
        return list;
    }

    @Override
    public Map<Long, List<Long>> getSubDepIdMap(String corpid, boolean showHidden) {
        Map<Long, List<Long>> result = new HashMap<>(1 << 4);
        if (paasRedisHelper.hasKey(RedisPrefixConstant.SUB_DEP_ID_MAP, corpid)) {
            //存在缓存
            Map<Object, Object> map = paasRedisHelper.getAllHashValue(RedisPrefixConstant.SUB_DEP_ID_MAP, corpid);
            map.forEach((key, value) -> {
                try {
                    result.put(Long.valueOf(key.toString()), JSON.parseArray(value.toString(), Long.class));
                } catch (NumberFormatException | ClassCastException e1) {
                    //do nothing
                }
            });
            return result;
        }
        List<DepartmentEntity> departmentEntityList = new ArrayList<>();
        try {

            departmentEntityList = findAllDepartment(corpid, showHidden);
        } catch (Exception e){
            log.error("DepartmentModelImpl.getSubDepIdMap error:", e);
        }
        Map<Object, Object> redisResult = new HashMap<>(departmentEntityList.size());
        for (DepartmentEntity departmentEntity : departmentEntityList) {
            String depIdRouter = departmentEntity.getDepIdRouter();
            String[] depStringArr = depIdRouter.split("\\|");
            List<Long> subDepIdList = new ArrayList<>();
            for (String s : depStringArr) {
                if (!StringUtil.isEmpty(s)) {
                    Long depId = null;
                    try {
                        depId = Long.valueOf(s);
                    } catch (NumberFormatException e) {
                        //do nothing
                    }
                    if (depId != null) {
                        subDepIdList.add(depId);
                    }
                }
            }
            result.put(departmentEntity.getId(), subDepIdList);
            redisResult.put(departmentEntity.getId().toString(), JSON.toJSONString(subDepIdList));
        }
        paasRedisHelper.setAllHashValue(RedisPrefixConstant.SUB_DEP_ID_MAP, corpid, redisResult, null);
        return result;
    }
}
